package com.zhuyuan.auth.config;

import com.zhuyuan.redis.RedisService;
import com.zhuyuan.security.service.UserDetailsImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.*;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: 张琳凯
 * @Description: Token配置类
 * @DateTime: 2025/1/6 20:40
 **/
@Configuration
@RequiredArgsConstructor
public class TokenConfig {

    private final RedisService redisService;

    /**
     * 配置令牌管理
     */
    @Bean
    public AuthorizationServerTokenServices tokenService(ClientDetailsService clientDetailsService, TokenStore tokenStore
            , JwtAccessTokenConverter accessTokenConverter,TokenEnhancer tokenEnhancer) {
        DefaultTokenServices service =new DefaultTokenServices();
        service.setClientDetailsService(clientDetailsService);
        service.setSupportRefreshToken(true);
        service.setTokenStore(tokenStore);
        //jwt
        TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
        List<TokenEnhancer> list = Arrays.asList(tokenEnhancer, accessTokenConverter);
        tokenEnhancerChain.setTokenEnhancers(list);
        service.setTokenEnhancer(tokenEnhancerChain);
        return service;
    }

    /**
     * @description: 将用户信息放入token中
     **/
    @Bean
    public TokenEnhancer tokenEnhancer() {

        return new TokenEnhancer() {
            @Override
            public OAuth2AccessToken enhance(OAuth2AccessToken oAuth2AccessToken, OAuth2Authentication oAuth2Authentication) {

                // 对于客户端鉴权模式，直接返回token
                if (oAuth2Authentication.getUserAuthentication() == null) {
                    return oAuth2AccessToken;
                }

                // 把当前登录用户需要的信息放入jwt token中
                final Map<String, Object> additionMessage = new HashMap<>(2);
                UserDetailsImpl user = (UserDetailsImpl) oAuth2Authentication.getUserAuthentication().getPrincipal();
                if (user != null) {
                    //这个是额外的信息，比如返回除token外的其他用户信息，或者在token过滤器中解析token获取有用信息组成UserDetailsIml(JwtAuthenticationFilter)
                    additionMessage.put("userId", user.getUserId());
                    additionMessage.put("userName", user.getUsername());
                }
                ((DefaultOAuth2AccessToken) oAuth2AccessToken).setAdditionalInformation(additionMessage);
                return oAuth2AccessToken;
            }
        };
    }

}
